/*
 * @Author: 吴世扬
 * @Date: 2022-09-10 17:43:55
 * @LastEditors: 吴世扬 18368095041@163.com
 * @LastEditTime: 2025-02-13 09:12:53
 * @FilePath: /vue3-admin/src/utils/request.ts
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
import axios, {
    type InternalAxiosRequestConfig,
    type AxiosResponse
} from 'axios';
import { ElMessage, ElMessageBox } from 'element-plus';
import { getToken } from '@/utils/auth';
import { useUserStore } from '@/store';

import router from '@/router/index';

let tipIsShou = false; // 提示是否在开启

const errorCode: Record<string, string> = {
    401: '认证失败，无法访问系统资源',
    403: '当前操作没有权限',
    404: '访问资源不存在',
    default: '网络信号差，请稍后再试'
};

// 创建 axios 实例
const service = axios.create({
    baseURL: import.meta.env.VITE_APP_BASE_API,
    timeout: 60000,
    headers: { 'Content-Type': 'application/json;charset=utf-8' }
});

const fitlerUtf8mb4 = (str: any) => {
    let newStr = '';
    for (const c of str) {
        if (c.codePointAt(0) <= 65535) {
            newStr += c;
        }
    }
    return newStr;
};
const filterObject = (data: any) => {
    const dataType = Object.prototype.toString.call(data);
    if (dataType === '[object Object]') {
        const keys = Object.keys(data);
        keys.forEach((key) => {
            const value = data[key];
            const valueType = Object.prototype.toString.call(value);
            if (valueType === '[object Object]') {
                filterObject(value);
            } else if (valueType === '[object Array]') {
                value.forEach((item: any) => {
                    filterObject(item);
                });
            } else if (valueType === '[object String]') {
                data[key] = fitlerUtf8mb4(value);
            }
        });
    } else if (dataType === '[object Array]') {
        data.forEach((item: any) => {
            filterObject(item);
        });
    }
};

// 请求拦截器
service.interceptors.request.use(
    (config: InternalAxiosRequestConfig) => {
        // 是否需要设置 token
        const isToken = (config.headers || {}).isToken === false;
        if (getToken() && !isToken) {
            config.headers && (config.headers.token = getToken()); // 让每个请求携带自定义token 请根据实际情况自行修改
        }
        // get请求映射params参数
        if (config.method === 'get' && config.params) {
            let url = `${config.url}?`;
            filterObject(config.params);
            // Object.keys(config.params).forEach(propName => {
            //     const value = config.params[propName];
            //     const part = `${encodeURIComponent(propName)}=`;
            //     if (value !== null && typeof value !== 'undefined') {
            //         if (typeof value === 'object') {
            //             Object.keys(value).forEach(key => {
            //                 const params = `${propName}[${key}]`;
            //                 const subPart = `${encodeURIComponent(params)}=`;
            //                 url += `${subPart + encodeURIComponent(value[key])}&`;
            //             });
            //         } else {
            //             url += `${part + encodeURIComponent(value)}&`;
            //         }
            //     }
            // });
            url = url.slice(0, -1);
            config.params = {};
            config.url = url;
        }
        if (config.method == 'post') {
            filterObject(config.data);
        }
        return config;
    },
    (error) => {
        //console.log(1,error);
        Promise.reject(error);
    }
);

// 响应拦截器
service.interceptors.response.use(
    (res: AxiosResponse) => {
        //console.log(82,res)
        // 未设置状态码则默认成功状态
        const code = res.data.code || 0;
        if (code !== 0) {
            ElMessage({
                message: res.data.msg,
                type: 'error'
            });
            if (code == -1) {
                // 延迟跳转避免正在跳转导致无法跳转
                setTimeout(() => {
                    router.push(`/login?redirect=`);
                }, 800);
                return Promise.reject(res);
            }
            return Promise.reject(res);
        }
        return res;
    },
    (error) => {
        console.log(1, error);
        const msg =
            (error.response.data && error.response.data.msg) ||
            errorCode[error.response.status] ||
            errorCode.default;
        console.log(2, error);
        if (error.response.status === 401) {
            if (error.config.url === '/admin/api/login/logout') return; // 登出接口返回401不弹出重新登录框
            if (router.currentRoute.value.path !== '/login') {
                if (tipIsShou) return;
                tipIsShou = true;
                ElMessageBox.confirm(msg, '系统提示', {
                    confirmButtonText: '重新登录',
                    cancelButtonText: '取消',
                    type: 'warning'
                })
                    .then(() => {
                        const userStore = useUserStore();
                        userStore.fedLogout().then(() => {
                            const route = router.currentRoute.value;
                            router.push({
                                path: '/login',
                                query: {
                                    redirect:
                                        route.path === '/login'
                                            ? '/'
                                            : route.path
                                }
                            });
                        });
                    })
                    .catch(() => {})
                    .finally(() => {
                        tipIsShou = false;
                    });
            }
        } else {
            ElMessage({
                message: msg,
                type: 'error'
            });
        }
        return Promise.reject(error);
    }
);

// 导出 axios 实例
export const request = service;
